﻿using Microsoft.EntityFrameworkCore;
using HttpMethod = Devonline.Core.HttpMethod;

namespace Devonline.Entity;

/// <summary>
/// 资源, 字符串类型的默认实现
/// </summary>
[Table("resource"), DisplayName("资源"), Index(nameof(Code), IsUnique = true)]
public class Resource : Resource<string>, IIdentity, IParent, IEntitySetWithCreateAndUpdate
{
    /// <summary>
    /// 所属系统, 用于标记当前资源属于那个系统, 以简化资源内容描述
    /// </summary>
    [ForeignKey(nameof(SystemId))]
    public virtual Resource? System { get; set; }
    /// <summary>
    /// 父级资源
    /// </summary>
    [ForeignKey(nameof(ParentId))]
    public virtual Resource? Parent { get; set; }
    /// <summary>
    /// 资源级别
    /// </summary>
    public virtual Level? Level { get; set; }

    /// <summary>
    /// 通用附件集合, NotMapped Attachments 用于记录实体对象上上传的附件
    /// </summary>
    [NotMapped]
    public virtual ICollection<Attachment>? Attachments { get; set; }
}

/// <summary>
/// 资源的定义
/// </summary>
[Table("resource"), DisplayName("资源"), Index(nameof(Code), IsUnique = true)]
public abstract class Resource<TKey> : Identity<TKey>, IIdentity<TKey>, IParent<TKey>, IEntitySetWithCreateAndUpdate<TKey> where TKey : IConvertible
{
    /// <summary>
    /// 所属系统编号, 用于标记当前资源属于那个系统, 以简化资源内容描述
    /// </summary>
    [Column("system_id"), DisplayName("所属系统编号"), MaxLength(36), Excel]
    public virtual TKey? SystemId { get; set; }
    /// <summary>
    /// 父级资源编号
    /// </summary>
    [Column("parent_id"), DisplayName("父级资源编号"), MaxLength(36), Excel]
    public virtual TKey? ParentId { get; set; }
    /// <summary>
    /// 资源所有者编号
    /// </summary>
    [Column("owner_id"), DisplayName("资源所有者"), MaxLength(36), Excel]
    public virtual TKey? OwnerId { get; set; }
    /// <summary>
    /// 资源所有者类型 OwnerType 枚举值
    /// </summary>
    [Column("owner_type", TypeName = "varchar(16)"), DisplayName("资源所有者类型"), Excel]
    public virtual IdentityType OwnerType { get; set; }
    /// <summary>
    /// 资源类型 ResourceType 枚举类型的值
    /// </summary>
    [Column("resource_type", TypeName = "varchar(16)"), DisplayName("资源类型"), Excel]
    public virtual ResourceType ResourceType { get; set; }
    /// <summary>
    /// 资源级别, 即资源定义的最低访问级别
    /// </summary>
    [Column("level_id"), DisplayName("资源级别"), MaxLength(36), Excel]
    public virtual TKey? LevelId { get; set; }
    /// <summary>
    /// 名称
    /// </summary>
    [Column("name"), Required, MaxLength(255), DisplayName("名称"), Excel]
    public override string? Name { get; set; } = null!;
    /// <summary>
    /// 资源编号, 用于内部命名, 排序等
    /// 资源访问的统一规则制定的总体约束, 形如: R35, #35
    /// </summary>
    [Column("code"), DisplayName("资源编号"), Required, Unique, MaxLength(36), Excel]
    public virtual string Code { get; set; } = null!;
    /// <summary>
    /// 资源标题
    /// </summary>
    [Column("title"), DisplayName("资源标题"), Required, MaxLength(36), Excel]
    public virtual string Title { get; set; } = null!;
    /// <summary>
    /// 资源保存的具体内容, 可能是密文
    /// </summary>
    [Column("content"), DisplayName("资源内容"), Required, MaxLength(1024), Excel]
    public virtual string Content { get; set; } = null!;
    /// <summary>
    /// 资源定义的可访问级别 AccessLevel 枚举类型的值
    /// </summary>
    [Column("access_level", TypeName = "varchar(16)"), DisplayName("访问级别"), Excel]
    public virtual AccessLevel AccessLevel { get; set; }
    /// <summary>
    /// 仅适用于 Http/Https 协议的资源, 资源的访问方式接口类型
    /// </summary>
    [Column("http_method", TypeName = "varchar(128)"), DisplayName("接口类型"), Excel]
    public virtual HttpMethod? HttpMethod { get; set; }
    /// <summary>
    /// 是否显示, 用于绘制菜单等时, 确认是否需要显示出来
    /// </summary>
    [Column("display"), DisplayName("是否显示"), Excel]
    public virtual bool Display { get; set; }
}